#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include <security/pam_appl.h>
#include <security/pam_modules.h>

#define MODULE_NAME   "pam_wityuan_auth"

PAM_EXTERN int pam_sm_setcred( pam_handle_t *pamh, int flags, int argc, const char **argv ) 
{
    return PAM_SUCCESS ;
}

static int converse(pam_handle_t *pamh, int nargs,
                    const struct pam_message **message,
                    struct pam_response **response) {
  struct pam_conv *conv;
  int retval = pam_get_item(pamh, PAM_CONV, (void *)&conv);
  if (retval != PAM_SUCCESS) {
    return retval;
  }
  return conv->conv(nargs, message, response, conv->appdata_ptr);
}


PAM_EXTERN int pam_sm_authenticate( pam_handle_t *pamh, int flags,int argc, const char **argv )
{
    const struct pam_message msg = { 
                    .msg_style = PAM_PROMPT_ECHO_ON,
                    .msg       = "wityuan Verfication Code:" };
    struct pam_response *resp = NULL;
    const struct pam_message *msgs = &msg;

    int retval = converse(pamh, 1, &msgs, &resp);
    char *ret = NULL;
    if (retval != PAM_SUCCESS || resp == NULL || resp->resp == NULL ||
      *resp->resp == '\000') 
    {
        if (retval == PAM_SUCCESS && resp && resp->resp) 
        {
            ret = resp->resp;
        }
    } 
    else 
    {
        ret = resp->resp;
    }

    // Deallocate temporary storage
    if (resp) 
    {
        if (!ret) 
        {
            free(resp->resp);
            free(resp);
            return PAM_AUTH_ERR;
        }     

        if( strcmp(resp->resp, "wityuan")==0 ) 
        {
            free(resp->resp);
            free(resp);
            return PAM_SUCCESS;
        }
        
        if (!ret) 
        {
            free(resp->resp);
        }
        free(resp);
    }

    return PAM_SUCCESS;
}

int pam_authentication()
{
    printf("pam_authentication ok\n");
    return 0;
}


#ifdef PAM_STATIC
struct pam_module _pam_listfile_modstruct = {
  MODULE_NAME,
  pam_sm_authenticate,
  pam_sm_setcred,
  NULL,
  NULL,
  NULL,
  NULL
};
#endif

